package org.lionsoul.websnail;

import org.lionsoul.websnail.analyzer.AnalyzerFactory;
import org.lionsoul.websnail.analyzer.DefaultAnalyzerFactory;
import org.lionsoul.websnail.downloader.Downloader;
import org.lionsoul.websnail.downloader.DownloaderFactory;
import org.lionsoul.websnail.downloader.Proxy;
import org.lionsoul.websnail.listener.DefaultSpiderListener;
import org.lionsoul.websnail.listener.DefaultTaskListener;
import org.lionsoul.websnail.listener.SpiderListener;
import org.lionsoul.websnail.listener.TaskListener;
import org.lionsoul.websnail.store.HashMapVisited;
import org.lionsoul.websnail.store.LinkedListTodo;
import org.lionsoul.websnail.store.Todo;
import org.lionsoul.websnail.store.Visited;
import org.lionsoul.websnail.task.DefaultTaskFactory;
import org.lionsoul.websnail.task.TaskFactory;
import org.lionsoul.websnail.util.LinkExtractor;
import org.lionsoul.websnail.util.UrlProcessor;

/**
 * Spider options class
 *
 * @author yangjian
 */

public class SpiderOptions
{
    public static final String USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36";
    public static final int TASK_INTERVAL = 1000; // 默认的任务间隔时间，1s
    public static final int WORKER_BUSY_SLEEP_TIME = 2000; // 默认 worker 繁忙时候等待时间，2s
    public static final int CONNECT_TIMEOUT = 10000; // 默认HTTP 连接超时时间，10s

    // 网页默认的字符编码
    private String charset = "UTF-8";

    // 浏览器代理头信息
    private String userAgent = USER_AGENT;

    // 任务间隔时间
    private int taskInterval = TASK_INTERVAL;

    // http 连接超时时间
    private int connectTimeout = CONNECT_TIMEOUT;

    // worker 任务繁忙时添加任务等待时间
    private int workerBusySleepTime = WORKER_BUSY_SLEEP_TIME;

    // http 代理
    private Proxy proxy;

    // todo list store handler
    private Todo todoHandler;

    // visited list store handler
    private Visited visitedHandler;

    // page download task creator
    private TaskFactory taskFactory;

    // page analyzer factory
    private AnalyzerFactory analyzerFactory;

    // download task listener
    private TaskListener taskListener;

    // spider listener
    private SpiderListener spiderListener;

    // url processor
    private UrlProcessor urlProcessor;

    // page downloader
    private Downloader downloader;
    private String downloaderType = Downloader.HTTP_CLIENT; // use http downloader as default

    // 页面超链接提取器
    private LinkExtractor linkExtractor;

    public static SpiderOptions custom()
    {
        return new SpiderOptions();
    }

    // 初始化 SpiderOption 属性，构建完整的对象
    public SpiderOptions build()
    {
        if (null == analyzerFactory) {
            analyzerFactory = new DefaultAnalyzerFactory();
        }
        if (null == todoHandler) {
            todoHandler = new LinkedListTodo();
        }
        if (null == visitedHandler) {
            visitedHandler = new HashMapVisited();
        }
        if (null == spiderListener) {
            spiderListener = new DefaultSpiderListener();
        }
        if (null == taskListener) {
            taskListener = new DefaultTaskListener();
        }
        if (null == taskFactory) {
            taskFactory = new DefaultTaskFactory();
        }
        // 初始化下载器
        if (null == downloader) {
            downloader = DownloaderFactory.getDownloader(downloaderType, proxy);
        }

        return this;
    }

    public String getCharset()
    {
        return charset;
    }

    public SpiderOptions setCharset(String charset)
    {
        this.charset = charset;
        return this;
    }

    public String getUserAgent()
    {
        return userAgent;
    }

    public SpiderOptions setUserAgent(String userAgent)
    {
        this.userAgent = userAgent;
        return this;
    }

    public int getTaskInterval()
    {
        return taskInterval;
    }

    public SpiderOptions setTaskInterval(int taskInterval)
    {
        this.taskInterval = taskInterval;
        return this;
    }

    public int getConnectTimeout()
    {
        return connectTimeout;
    }

    public SpiderOptions setConnectTimeout(int connectTimeout)
    {
        this.connectTimeout = connectTimeout;
        return this;
    }

    public int getWorkerBusySleepTime()
    {
        return workerBusySleepTime;
    }

    public SpiderOptions setWorkerBusySleepTime(int workerBusySleepTime)
    {
        this.workerBusySleepTime = workerBusySleepTime;
        return this;
    }

    public Proxy getProxy()
    {
        return proxy;
    }

    public SpiderOptions setProxy(Proxy proxy)
    {
        this.proxy = proxy;
        return this;
    }

    public Todo getTodoHandler()
    {
        return todoHandler;
    }

    public SpiderOptions setTodoHandler(Todo todoHandler)
    {
        this.todoHandler = todoHandler;
        return this;
    }

    public Visited getVisitedHandler()
    {
        return visitedHandler;
    }

    public SpiderOptions setVisitedHandler(Visited visitedHandler)
    {
        this.visitedHandler = visitedHandler;
        return this;
    }

    public TaskFactory getTaskFactory()
    {
        return taskFactory;
    }

    public SpiderOptions setTaskFactory(TaskFactory taskFactory)
    {
        this.taskFactory = taskFactory;
        return this;
    }

    public AnalyzerFactory getAnalyzerFactory()
    {
        return analyzerFactory;
    }

    public SpiderOptions setAnalyzerFactory(AnalyzerFactory analyzerFactory)
    {
        this.analyzerFactory = analyzerFactory;
        return this;
    }

    public TaskListener getTaskListener()
    {
        return taskListener;
    }

    public SpiderOptions setTaskListener(TaskListener taskListener)
    {
        this.taskListener = taskListener;
        return this;
    }

    public SpiderListener getSpiderListener()
    {
        return spiderListener;
    }

    public SpiderOptions setSpiderListener(SpiderListener spiderListener)
    {
        this.spiderListener = spiderListener;
        return this;
    }

    public UrlProcessor getUrlProcessor()
    {
        return urlProcessor;
    }

    public SpiderOptions setUrlProcessor(UrlProcessor urlProcessor)
    {
        this.urlProcessor = urlProcessor;
        return this;
    }

    public Downloader getDownloader()
    {
        return downloader;
    }

    public SpiderOptions setDownloader(Downloader downloader)
    {
        this.downloader = downloader;
        return this;
    }

    public SpiderOptions setDownloader(String downloader)
    {
        this.downloaderType = downloader;
        return this;
    }

    public LinkExtractor getLinkExtractor()
    {
        return linkExtractor;
    }

    public SpiderOptions setLinkExtractor(LinkExtractor linkExtractor)
    {
        this.linkExtractor = linkExtractor;
        return this;
    }
}
